home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 351-375 / disk_360 / uucp / uucp0.lzh / src / lib / alias.c next >
C/C++ Source or Header  |  1990-04-04  |  5KB  |  248 lines

  1.  
  2. /*
  3.  *  ALIAS.C
  4.  *
  5.  *  $Header: Beta:src/uucp/src/lib/RCS/alias.c,v 1.1 90/02/02 12:08:24 dillon Exp Locker: dillon $
  6.  *
  7.  *  (C) Copyright 1989-1990 by Matthew Dillon,  All Rights Reserved.
  8.  *
  9.  *  Interpret UULIB:Aliases file.  To save space we do not load
  10.  *  the entire file, just sections on demand.
  11.  *
  12.  *  #    = comment
  13.  *  id: name [, name...]
  14.  *
  15.  *  name is a user name, path, or |filter, or quoted name.  Example,
  16.  *  "|more" or "|rnews"
  17.  */
  18.  
  19. #include <stdio.h>
  20. #include <stdlib.h>
  21. #include <fcntl.h>
  22. #include <time.h>
  23. #include "config.h"
  24.  
  25. #include "log.h"
  26.  
  27. #define HASHSIZE    256
  28. #define HASHMASK    (HASHSIZE-1)
  29.  
  30. #define HF_TERM     0x01    /*    terminator name     */
  31. #define HF_ALIAS    0x02    /*    alias            */
  32. #define HF_LOADED   0x04    /*    def loaded        */
  33.  
  34. typedef struct Hash {
  35.     struct Hash *Next;
  36.     short   NumAlias;    /*  # of aliases    */
  37.     short   Flags;
  38.     char    *Name;    /*  aliased user name    */
  39.     union {
  40.     struct Hash    **Alias;    /*  list of aliases       */
  41.     long    Offset;     /*    offset into file    */
  42.     } u;
  43. } Hash;
  44.  
  45. Prototype void LoadAliases(void);
  46. Prototype void UserAliasList(const char *, void (*)(const char *));
  47.  
  48. Local Hash *FindHashObject(const char *);
  49. Local void LoadHashObject(Hash *);
  50. Local int  HashFunc(const char *);
  51.  
  52.  
  53. static Hash    *HashTab[HASHSIZE];
  54. static char    Tmp[256];
  55.  
  56. void
  57. LoadAliases()
  58. {
  59.     FILE *fi = fopen(MakeConfigPath(UULIB, "Aliases"), "r");
  60.     short i;
  61.     short j;
  62.     short k;
  63.     short line = 0;
  64.     long newoffset = 0;
  65.     long offset;
  66.     Hash *h;
  67.     char *buf = Tmp;
  68.  
  69.     if (fi == NULL) {
  70.     ulog(-1, "Can't open %s", MakeConfigPath(UULIB, "Aliases"));
  71.     return;
  72.     }
  73.     while (fgets(buf, 256, fi)) {
  74.     offset = newoffset;
  75.     newoffset = ftell(fi);
  76.     ++line;
  77.     for (i = 0; buf[i] == ' ' || buf[i] == 9; ++i);
  78.     if (buf[i] == '#' || buf[i] == '\n')
  79.         continue;
  80.     for (j = i; buf[j] && buf[j] != ':'; ++j);
  81.     if (buf[j] == 0) {
  82.         ulog(-1, "No Colon %s line %d", MakeConfigPath(UULIB, "Aliases"), line);
  83.         continue;
  84.     }
  85.     buf[j] = 0;
  86.  
  87.     k = HashFunc(buf + i);
  88.     h = malloc(sizeof(Hash));
  89.     h->Next = HashTab[k];
  90.     h->NumAlias = 0;
  91.     h->Flags = HF_ALIAS;
  92.     h->Name = malloc(strlen(buf+i) + 1);
  93.     h->u.Offset = offset + j + 1;
  94.     strcpy(h->Name, buf + i);
  95.  
  96.     HashTab[k] = h;
  97.  
  98.     /*
  99.      *  if trailing comma, list continues onto next line
  100.      */
  101.  
  102.     for (;;) {
  103.         for (++j; buf[j]; ++j);
  104.         while (buf[j-1] == ' ' || buf[j-1] == 9 || buf[j-1] == '\n')
  105.         --j;
  106.         if (buf[j-1] != ',')
  107.         break;
  108.         if (fgets(buf, 256, fi) == NULL)
  109.         break;
  110.         newoffset = ftell(fi);
  111.         j = 0;
  112.     }
  113.     }
  114.     fclose(fi);
  115. }
  116.  
  117. static
  118. Hash *
  119. FindHashObject(name)
  120. const char *name;
  121. {
  122.     short k = HashFunc(name);
  123.     Hash *h;
  124.  
  125.     for (h = HashTab[k]; h; h = h->Next) {
  126.     if (strcmp(name, h->Name) == 0)
  127.         return(h);
  128.     }
  129.     return(NULL);
  130. }
  131.  
  132. static
  133. void
  134. LoadHashObject(hash)
  135. Hash *hash;
  136. {
  137.     FILE *fi = fopen(MakeConfigPath(UULIB, "Aliases"), "r");
  138.     char *buf = Tmp;
  139.     short i, j;
  140.     short c;
  141.     short numalloc = 4;
  142.     Hash **hv = malloc(sizeof(Hash *) * 4);
  143.     Hash *h;
  144.  
  145.     if (fi == NULL) {
  146.     ulog(-1, "Can't open %s", MakeConfigPath(UULIB, "Aliases"));
  147.     return;
  148.     }
  149.  
  150.     hash->Flags |= HF_LOADED;
  151.     fseek(fi, hash->u.Offset, 0);
  152.     while (fgets(buf, 256, fi)) {
  153.     i = 0;
  154.     c = 'x';
  155.  
  156.     for (;;) {
  157.         while (buf[i] == ' ' || buf[i] == 9)
  158.         ++i;
  159.         if (buf[i] == 0 || buf[i] == '\n')
  160.         break;
  161.  
  162.         for (j = i; buf[j] != '\n' && buf[j] != ' ' && buf[j] != 9 && buf[j] != ','; ++j) {
  163.         if (buf[j] == '\"') {
  164.             i = j + 1;
  165.             for (++j; buf[j] != '\n' && buf[j] != '\"'; ++j);
  166.             break;
  167.         }
  168.         }
  169.         c = buf[j];
  170.         buf[j] = 0;
  171.  
  172.         if ((h = FindHashObject(buf + i)) == NULL) {
  173.         short k = HashFunc(buf + i);
  174.  
  175.         h = malloc(sizeof(Hash));
  176.         h->Next = HashTab[k];
  177.         h->NumAlias = 0;
  178.         h->Flags = HF_TERM;
  179.         h->Name = malloc(strlen(buf + i) + 1);
  180.         h->u.Alias = NULL;
  181.         strcpy(h->Name, buf + i);
  182.  
  183.         HashTab[k] = h;
  184.         }
  185.  
  186.         if (hash->NumAlias == numalloc) {
  187.         Hash **hvo = hv;
  188.         short add = 4;
  189.  
  190.         hv = malloc(sizeof(Hash *) * (numalloc + add));
  191.         movmem((char *)hvo, (char *)hv, sizeof(Hash *) * numalloc);
  192.         numalloc += add;
  193.         }
  194.         hv[hash->NumAlias++] = h;
  195.  
  196.         i = j + 1;
  197.         if (c == '\"')
  198.         c = buf[i++];
  199.         if (c == '\n' || c == 0)
  200.         i = j;
  201.     }
  202.     if (c != ',')
  203.         break;
  204.     }
  205.     hash->u.Alias = hv;
  206. }
  207.  
  208. void
  209. UserAliasList(user, callback)
  210. const char *user;
  211. void (*callback)(const char *);
  212. {
  213.     short i;
  214.     Hash *hash = FindHashObject(user);
  215.     static short stack;
  216.  
  217.     if (++stack == 32) {
  218.     ulog(-1, "%s recursion near user %s", MakeConfigPath(UULIB, "Aliases"), user);
  219.     --stack;
  220.     return;
  221.     }
  222.  
  223.     if (hash && (hash->Flags & HF_TERM) == 0) {
  224.     if ((hash->Flags & HF_LOADED) == 0)
  225.         LoadHashObject(hash);
  226.     for (i = 0; i < hash->NumAlias; ++i) {
  227.         Hash *h = hash->u.Alias[i];
  228.         UserAliasList(h->Name, callback);
  229.     }
  230.     } else {
  231.     (*callback)(user);
  232.     }
  233.     --stack;
  234. }
  235.  
  236. static int
  237. HashFunc(str)
  238. const char *str;
  239. {
  240.     unsigned long v = 0x14FBA5C3;
  241.     while (*str) {
  242.     v = (v << 5) ^ (*str & 0x1F) ^ (v >> 27);
  243.     ++str;
  244.     }
  245.     return((int)(v & HASHMASK));
  246. }
  247.  
  248.